﻿using System;
using System.Collections.Generic;
using System.Linq;
using Citi.Scheduler.Domain.Utils;

namespace Citi.Scheduler.Domain
{
    public partial class Routine
    {
        public bool HasPredecessor
        {
            get { return PredecessorRoutineId.HasValue; }
        }

        public int TotalMinutesExecution
        {
            get { return EstimatedTime + EstimatedTime * PercentageAcceptableVariation / 100; }
        }

        public IEnumerable<Routine> GetRoutinesByLibraryIdAndType(int libraryId, int type)
        {
            return SelectAllActive<Routine>().Where(x => x.LibraryVersion.LibraryId == libraryId && x.LibraryVersion.Type == type);
        }

        public Routine GetRoutineByName(string name)
        {
            return SelectAllActive<Routine>().FirstOrDefault(x => x.Name == name);
        }

        public IEnumerable<Routine> GetRoutinesByLibraryIdAndTypeUsingLastVersion(int libraryId, int type)
        {
            return GetRoutinesByLibraryIdAndType(libraryId, type).Where(x => x.UseLastVersion);
        }

        public void FinishExpiredRoutines()
        {
            Console.WriteLine("{0} Checking executions with expired schedule", DateTime.Now.ToString("dd/MM/yyy HH:mm:ss"));

            try
            {
                var routines = SelectAllActive<Routine>()
                    .Where(x => x.RoutineSchedules.Any() && !x.ScheduleFinished
                        && (((x.RoutineSchedules.Last().Schedule.EndsOn != null && x.RoutineSchedules.Last().Schedule.EndsOn < DateTime.Today)
                        || (x.RoutineSchedules.Last().Schedule.EndsAfter != null
                            && x.RoutineSchedules.Last().Schedule.EndsAfter >= x.RoutineExecutions.Count() - x.RoutineOnDemands.Count(y => y.SentToExecution))))).ToList();

                Console.WriteLine("{1} Finishing {0} execution(s) with expired schedule", routines.Count, DateTime.Now.ToString("dd/MM/yyy HH:mm:ss"));

                routines.ForEach(x =>
                    {
                        x.ScheduleFinished = true;
                        x.Save(x);
                    });
            }
            catch (Exception e)
            {
                Console.WriteLine("{0} Finishing Error: {1}", DateTime.Now.ToString("dd/MM/yyy HH:mm:ss"), e.Message);
            }
        }

        public void RecursiveLoad(string parent)
        {
          //var ParentFromDatabase = Context.Instance.Entry(parent).Collection(d=>d.Children);//Children are loaded, we can loop them now
   
          //foreach (var child in parent.Children)
          //{
          //  _context.Entry(child).Reference(d=>d.OtherProperty).Load();
          //  RecursiveLoad(child);
          //}
          //return ParentFromDatabase;
        }

        public IEnumerable<Routine> GetAllHierarchy()
        {
            var routines = new List<Routine>();
            var currentParent = this.PredecessorRoutine;

            while (currentParent != null)
            {
                routines.Insert(0, currentParent);
                currentParent = currentParent.PredecessorRoutine;
            }

            routines.AddRange(this.GetAllChildren());

            return routines;
        }

        public IEnumerable<Routine> GetAllChildren()
        {
            var routines = new List<Routine> { this };

            foreach (var child in Routines)
                routines.AddRange(child.GetAllChildren());

            return routines;
        }
    }
}
